#ifndef SMARTCONTAINER_H_
#define SMARTCONTAINER_H_

#include <map>
#include <vector>

template< class K, class V >
class CSmartMap
{

private:
	
	std::map< K, V * > m_pObjects;


public:
	
	inline typename std::map< K, V * >::iterator begin()
	{
		
		return m_pObjects.begin();
		
	}

	inline typename std::map< K, V * >::iterator end()
	{
		
		return m_pObjects.end();
		
	}
	
	inline typename std::map< K, V * >::iterator erase( typename std::map< K, V * >::iterator it )
	{
		
		V * object = it->second;
		delete object;
		
		return m_pObjects.erase( it );
		
		
		
	}

	inline void clear()
	{
		
		for( typename std::map< K, V * >::iterator iter = begin();
			 iter != end(); iter++ )
			{
				
				V * object = iter->second;
				
				if( object )
					delete object;
				
				object = NULL;
				
			}
			
		m_pObjects.clear();
		
	}
	
	inline void set( const K & i, V * o )
	{
		
		m_pObjects[i] = o;
		
	}


	inline V * at( const K & i )
	{
		
		V * r = NULL;
		
		try
		{
		
			r = m_pObjects.at( i );
			
		} catch( std::exception & err )
		{ }
		
		return r;
		
	}
	

};


template< class T >
class CSmartVector
{

private:

	std::vector< T * > m_pObjects;


public:

	inline int size()
	{
		
		return m_pObjects.size();
		
	}
	
	inline typename std::vector< T * >::iterator begin()
	{
		
		return m_pObjects.begin();
		
	}

	inline typename std::vector< T * >::iterator end()
	{
		
		return m_pObjects.end();
		
	}	
	
	inline void push_back( T * o )
	{

		m_pObjects.push_back( o );

	}
	
	inline typename std::vector< T * >::iterator erase( typename std::vector< T * >::iterator it )
	{
		
		T * object = ( *it );
		
		delete object;
		
		return m_pObjects.erase( it );
		
	}
	
	inline void clear()
	{
		
		for( typename std::vector< T * >::iterator iter = begin();
			 iter != end(); )
			{
				
				T * object = ( *iter );
				iter = m_pObjects.erase( iter );
				
				if( object )
					delete object;
				
				object = NULL;
				
			}
			
		m_pObjects.clear();
			
		
	}
	
	inline T * operator[] ( int i )
	{
		
		return m_pObjects[i];
		
	}
	
	inline T * at( int i )
	{
		
		return m_pObjects.at( i );
		
	}

};



#endif
